package lang4j.parser.generated;
import java.io.Writer;
import java.io.PrintWriter;
import java.util.Iterator;
import org.apache.commons.lang.StringEscapeUtils;
import java.io.StringWriter;

public class Lang4jRenderer {
    PrintWriter out;

    /** Creates a new Renderer that works on the given writer. <strong>Note</strong> that the
        Writer is not closed by the Renderer. You have to make sure that a) the writer is open
        as long as you intend to use this instance and b) that you close the writer when done.

        @param writer output writer*/
    public Lang4jRenderer(Writer writer){
        out=new PrintWriter(writer);
    }

   public static String productionListToString(java.util.List productionList){
        StringWriter writer=new StringWriter();
        Lang4jRenderer renderer=new Lang4jRenderer(writer);
        renderer.renderProductionList(productionList);
        return writer.getBuffer().toString();
    }
    public void renderProductionList(java.util.List productionList){
        for(Iterator iter=productionList.iterator();iter.hasNext();){
            Production production = (Production) iter.next();
            renderProduction(production);
            out.print("\n");
        }
    }

   public static String lang4jGrammarToString(Lang4jGrammar lang4jGrammar){
        StringWriter writer=new StringWriter();
        Lang4jRenderer renderer=new Lang4jRenderer(writer);
        renderer.renderLang4jGrammar(lang4jGrammar);
        return writer.getBuffer().toString();
    }
    public void renderLang4jGrammar(Lang4jGrammar lang4jGrammar){
        if (lang4jGrammar.getComment()!=null){
        out.print("\""+StringEscapeUtils.escapeJava(lang4jGrammar.getComment())+"\"");
        out.print(" ");
        }
        out.print("grammarName ");
        out.print(":");
        out.print(lang4jGrammar.getName());
        out.print(" ");
        out.print(";");
        out.print("package ");
        out.print(":");
        out.print("\""+StringEscapeUtils.escapeJava(lang4jGrammar.getPackageName())+"\"");
        out.print(" ");
        out.print(";");
        renderProductionList(lang4jGrammar.getProductions());
        out.print(" ");
    }

   public static String productionToString(Production production){
        StringWriter writer=new StringWriter();
        Lang4jRenderer renderer=new Lang4jRenderer(writer);
        renderer.renderProduction(production);
        return writer.getBuffer().toString();
    }
    public void renderProduction(Production production){
    production.accept(new ProductionVisitor(){
        public void visitEnumProduction(EnumProduction enumProduction){
            renderEnumProduction(enumProduction);
        }
        public void visitTypeProduction(TypeProduction typeProduction){
            renderTypeProduction(typeProduction);
        }
        public void visitListProduction(ListProduction listProduction){
            renderListProduction(listProduction);
        }
    });
    }

   public static String typeProductionToString(TypeProduction typeProduction){
        StringWriter writer=new StringWriter();
        Lang4jRenderer renderer=new Lang4jRenderer(writer);
        renderer.renderTypeProduction(typeProduction);
        return writer.getBuffer().toString();
    }
    public void renderTypeProduction(TypeProduction typeProduction){
    typeProduction.accept(new TypeProductionVisitor(){
        public void visitInterfaceProduction(InterfaceProduction interfaceProduction){
            renderInterfaceProduction(interfaceProduction);
        }
        public void visitConstructorProduction(ConstructorProduction constructorProduction){
            renderConstructorProduction(constructorProduction);
        }
    });
    }

   public static String listProductionToString(ListProduction listProduction){
        StringWriter writer=new StringWriter();
        Lang4jRenderer renderer=new Lang4jRenderer(writer);
        renderer.renderListProduction(listProduction);
        return writer.getBuffer().toString();
    }
    public void renderListProduction(ListProduction listProduction){
    listProduction.accept(new ListProductionVisitor(){
        public void visitListProductionStar(ListProductionStar listProductionStar){
            renderListProductionStar(listProductionStar);
        }
        public void visitListProductionPow(ListProductionPow listProductionPow){
            renderListProductionPow(listProductionPow);
        }
    });
    }

   public static String listProductionStarToString(ListProductionStar listProductionStar){
        StringWriter writer=new StringWriter();
        Lang4jRenderer renderer=new Lang4jRenderer(writer);
        renderer.renderListProductionStar(listProductionStar);
        return writer.getBuffer().toString();
    }
    public void renderListProductionStar(ListProductionStar listProductionStar){
        out.print("list ");
        out.print(listProductionStar.getName());
        out.print(" ");
        out.print(":");
        out.print("(");
        renderListElementType(listProductionStar.getType());
        out.print(" ");
        out.print(")");
        out.print("*");
        out.print(";");
    }

   public static String listProductionPowToString(ListProductionPow listProductionPow){
        StringWriter writer=new StringWriter();
        Lang4jRenderer renderer=new Lang4jRenderer(writer);
        renderer.renderListProductionPow(listProductionPow);
        return writer.getBuffer().toString();
    }
    public void renderListProductionPow(ListProductionPow listProductionPow){
        out.print("list ");
        out.print(listProductionPow.getName());
        out.print(" ");
        out.print(":");
        out.print("(");
        renderListElementType(listProductionPow.getType());
        out.print(" ");
        out.print(")");
        out.print("^");
        out.print("(");
        renderTerminal(listProductionPow.getLit());
        out.print(" ");
        out.print(")");
        out.print(";");
    }

   public static String listElementTypeToString(ListElementType listElementType){
        StringWriter writer=new StringWriter();
        Lang4jRenderer renderer=new Lang4jRenderer(writer);
        renderer.renderListElementType(listElementType);
        return writer.getBuffer().toString();
    }
    public void renderListElementType(ListElementType listElementType){
    listElementType.accept(new ListElementTypeVisitor(){
        public void visitProductionReference(ProductionReference productionReference){
            renderProductionReference(productionReference);
        }
        public void visitReferenceElement(ReferenceElement referenceElement){
            renderReferenceElement(referenceElement);
        }
    });
    }

   public static String referenceElementToString(ReferenceElement referenceElement){
        StringWriter writer=new StringWriter();
        Lang4jRenderer renderer=new Lang4jRenderer(writer);
        renderer.renderReferenceElement(referenceElement);
        return writer.getBuffer().toString();
    }
    public void renderReferenceElement(ReferenceElement referenceElement){
        out.print("REFERENCE ");
        out.print(":");
        out.print(referenceElement.getProduction().getName());
        out.print(" ");
    }

   public static String productionReferenceToString(ProductionReference productionReference){
        StringWriter writer=new StringWriter();
        Lang4jRenderer renderer=new Lang4jRenderer(writer);
        renderer.renderProductionReference(productionReference);
        return writer.getBuffer().toString();
    }
    public void renderProductionReference(ProductionReference productionReference){
        out.print(productionReference.getProduction().getName());
        out.print(" ");
    }

   public static String enumProductionToString(EnumProduction enumProduction){
        StringWriter writer=new StringWriter();
        Lang4jRenderer renderer=new Lang4jRenderer(writer);
        renderer.renderEnumProduction(enumProduction);
        return writer.getBuffer().toString();
    }
    public void renderEnumProduction(EnumProduction enumProduction){
        out.print("enum ");
        out.print(enumProduction.getName());
        out.print(" ");
        out.print(":");
        renderLabelledTerminalList(enumProduction.getValues());
        out.print(" ");
        out.print(";");
    }

   public static String labelledTerminalToString(LabelledTerminal labelledTerminal){
        StringWriter writer=new StringWriter();
        Lang4jRenderer renderer=new Lang4jRenderer(writer);
        renderer.renderLabelledTerminal(labelledTerminal);
        return writer.getBuffer().toString();
    }
    public void renderLabelledTerminal(LabelledTerminal labelledTerminal){
        renderTerminal(labelledTerminal.getTerminal());
        out.print(" ");
        out.print(":");
        out.print(labelledTerminal.getLabel());
        out.print(" ");
    }

   public static String labelledTerminalListToString(java.util.List labelledTerminalList){
        StringWriter writer=new StringWriter();
        Lang4jRenderer renderer=new Lang4jRenderer(writer);
        renderer.renderLabelledTerminalList(labelledTerminalList);
        return writer.getBuffer().toString();
    }
    public void renderLabelledTerminalList(java.util.List labelledTerminalList){
        for(Iterator iter=labelledTerminalList.iterator();iter.hasNext();){
            LabelledTerminal labelledTerminal = (LabelledTerminal) iter.next();
            renderLabelledTerminal(labelledTerminal);
    if (iter.hasNext())         out.print("|");
        }
    }

   public static String interfaceProductionToString(InterfaceProduction interfaceProduction){
        StringWriter writer=new StringWriter();
        Lang4jRenderer renderer=new Lang4jRenderer(writer);
        renderer.renderInterfaceProduction(interfaceProduction);
        return writer.getBuffer().toString();
    }
    public void renderInterfaceProduction(InterfaceProduction interfaceProduction){
        out.print("interface ");
        out.print(interfaceProduction.getName());
        out.print(" ");
        if (interfaceProduction.getKeyField()!=null){
            out.print("(");
        out.print("key ");
                out.print(":");
        out.print(interfaceProduction.getKeyField());
        out.print(" ");
            out.print(")");
        }
        out.print(":");
        renderProductionReferenceList(interfaceProduction.getSubTypes());
        out.print(" ");
        out.print(";");
    }

   public static String productionReferenceListToString(java.util.List productionReferenceList){
        StringWriter writer=new StringWriter();
        Lang4jRenderer renderer=new Lang4jRenderer(writer);
        renderer.renderProductionReferenceList(productionReferenceList);
        return writer.getBuffer().toString();
    }
    public void renderProductionReferenceList(java.util.List productionReferenceList){
        for(Iterator iter=productionReferenceList.iterator();iter.hasNext();){
            TypeProduction typeProduction = (TypeProduction) iter.next();
        out.print(typeProduction.getName());
    if (iter.hasNext())         out.print("|");
        }
    }

   public static String constructorProductionToString(ConstructorProduction constructorProduction){
        StringWriter writer=new StringWriter();
        Lang4jRenderer renderer=new Lang4jRenderer(writer);
        renderer.renderConstructorProduction(constructorProduction);
        return writer.getBuffer().toString();
    }
    public void renderConstructorProduction(ConstructorProduction constructorProduction){
        out.print("class ");
        out.print(constructorProduction.getName());
        out.print(" ");
        if (constructorProduction.getKeyField()!=null){
            out.print("(");
        out.print("key ");
                out.print(":");
        out.print(constructorProduction.getKeyField());
        out.print(" ");
            out.print(")");
        }
        out.print(":");
        renderFactorList(constructorProduction.getFactors());
        out.print(" ");
        out.print(";");
    }

   public static String factorListToString(java.util.List factorList){
        StringWriter writer=new StringWriter();
        Lang4jRenderer renderer=new Lang4jRenderer(writer);
        renderer.renderFactorList(factorList);
        return writer.getBuffer().toString();
    }
    public void renderFactorList(java.util.List factorList){
        for(Iterator iter=factorList.iterator();iter.hasNext();){
            ProductionFactor productionFactor = (ProductionFactor) iter.next();
            renderProductionFactor(productionFactor);
            out.print("\n");
        }
    }

   public static String productionFactorToString(ProductionFactor productionFactor){
        StringWriter writer=new StringWriter();
        Lang4jRenderer renderer=new Lang4jRenderer(writer);
        renderer.renderProductionFactor(productionFactor);
        return writer.getBuffer().toString();
    }
    public void renderProductionFactor(ProductionFactor productionFactor){
    productionFactor.accept(new ProductionFactorVisitor(){
        public void visitTerminal(Terminal terminal){
            renderTerminal(terminal);
        }
        public void visitAttribute(Attribute attribute){
            renderAttribute(attribute);
        }
        public void visitOptionalAttributeList(OptionalAttributeList optionalAttributeList){
            renderOptionalAttributeList(optionalAttributeList);
        }
    });
    }

   public static String optionalAttributeListToString(OptionalAttributeList optionalAttributeList){
        StringWriter writer=new StringWriter();
        Lang4jRenderer renderer=new Lang4jRenderer(writer);
        renderer.renderOptionalAttributeList(optionalAttributeList);
        return writer.getBuffer().toString();
    }
    public void renderOptionalAttributeList(OptionalAttributeList optionalAttributeList){
        out.print("[");
        renderFactorList(optionalAttributeList.getFactors());
        out.print(" ");
        out.print("]");
    }

   public static String deepAttributeToString(DeepAttribute deepAttribute){
        StringWriter writer=new StringWriter();
        Lang4jRenderer renderer=new Lang4jRenderer(writer);
        renderer.renderDeepAttribute(deepAttribute);
        return writer.getBuffer().toString();
    }
    public void renderDeepAttribute(DeepAttribute deepAttribute){
        out.print(deepAttribute.getProduction().getName());
        out.print(" ");
        if (deepAttribute.getName()!=null){
            out.print(":");
        out.print(deepAttribute.getName());
        out.print(" ");
        }
    }

   public static String flatAttributeToString(FlatAttribute flatAttribute){
        StringWriter writer=new StringWriter();
        Lang4jRenderer renderer=new Lang4jRenderer(writer);
        renderer.renderFlatAttribute(flatAttribute);
        return writer.getBuffer().toString();
    }
    public void renderFlatAttribute(FlatAttribute flatAttribute){
    flatAttribute.accept(new FlatAttributeVisitor(){
        public void visitIntLiteralAttribute(IntLiteralAttribute intLiteralAttribute){
            renderIntLiteralAttribute(intLiteralAttribute);
        }
        public void visitDoubleLiteralAttribute(DoubleLiteralAttribute doubleLiteralAttribute){
            renderDoubleLiteralAttribute(doubleLiteralAttribute);
        }
        public void visitCharLiteralAttribute(CharLiteralAttribute charLiteralAttribute){
            renderCharLiteralAttribute(charLiteralAttribute);
        }
        public void visitBooleanLiteralAttribute(BooleanLiteralAttribute booleanLiteralAttribute){
            renderBooleanLiteralAttribute(booleanLiteralAttribute);
        }
        public void visitStringLiteralAttribute(StringLiteralAttribute stringLiteralAttribute){
            renderStringLiteralAttribute(stringLiteralAttribute);
        }
        public void visitIdentifierAttribute(IdentifierAttribute identifierAttribute){
            renderIdentifierAttribute(identifierAttribute);
        }
        public void visitReferenceAttribute(ReferenceAttribute referenceAttribute){
            renderReferenceAttribute(referenceAttribute);
        }
        public void visitMultiLineStringAttribute(MultiLineStringAttribute multiLineStringAttribute){
            renderMultiLineStringAttribute(multiLineStringAttribute);
        }
    });
    }

   public static String charLiteralAttributeToString(CharLiteralAttribute charLiteralAttribute){
        StringWriter writer=new StringWriter();
        Lang4jRenderer renderer=new Lang4jRenderer(writer);
        renderer.renderCharLiteralAttribute(charLiteralAttribute);
        return writer.getBuffer().toString();
    }
    public void renderCharLiteralAttribute(CharLiteralAttribute charLiteralAttribute){
        out.print("CHAR_LITERAL ");
        out.print(":");
        out.print(charLiteralAttribute.getName());
        out.print(" ");
    }

   public static String stringLiteralAttributeToString(StringLiteralAttribute stringLiteralAttribute){
        StringWriter writer=new StringWriter();
        Lang4jRenderer renderer=new Lang4jRenderer(writer);
        renderer.renderStringLiteralAttribute(stringLiteralAttribute);
        return writer.getBuffer().toString();
    }
    public void renderStringLiteralAttribute(StringLiteralAttribute stringLiteralAttribute){
        out.print("LITERAL ");
        out.print(":");
        out.print(stringLiteralAttribute.getName());
        out.print(" ");
    }

   public static String multiLineStringAttributeToString(MultiLineStringAttribute multiLineStringAttribute){
        StringWriter writer=new StringWriter();
        Lang4jRenderer renderer=new Lang4jRenderer(writer);
        renderer.renderMultiLineStringAttribute(multiLineStringAttribute);
        return writer.getBuffer().toString();
    }
    public void renderMultiLineStringAttribute(MultiLineStringAttribute multiLineStringAttribute){
        out.print("MULTI_LINE_LITERAL ");
        out.print(":");
        out.print(multiLineStringAttribute.getName());
        out.print(" ");
    }

   public static String intLiteralAttributeToString(IntLiteralAttribute intLiteralAttribute){
        StringWriter writer=new StringWriter();
        Lang4jRenderer renderer=new Lang4jRenderer(writer);
        renderer.renderIntLiteralAttribute(intLiteralAttribute);
        return writer.getBuffer().toString();
    }
    public void renderIntLiteralAttribute(IntLiteralAttribute intLiteralAttribute){
        out.print("INT_LITERAL ");
        out.print(":");
        out.print(intLiteralAttribute.getName());
        out.print(" ");
    }

   public static String identifierAttributeToString(IdentifierAttribute identifierAttribute){
        StringWriter writer=new StringWriter();
        Lang4jRenderer renderer=new Lang4jRenderer(writer);
        renderer.renderIdentifierAttribute(identifierAttribute);
        return writer.getBuffer().toString();
    }
    public void renderIdentifierAttribute(IdentifierAttribute identifierAttribute){
        out.print("IDENTIFIER ");
        out.print(":");
        out.print(identifierAttribute.getName());
        out.print(" ");
    }

   public static String doubleLiteralAttributeToString(DoubleLiteralAttribute doubleLiteralAttribute){
        StringWriter writer=new StringWriter();
        Lang4jRenderer renderer=new Lang4jRenderer(writer);
        renderer.renderDoubleLiteralAttribute(doubleLiteralAttribute);
        return writer.getBuffer().toString();
    }
    public void renderDoubleLiteralAttribute(DoubleLiteralAttribute doubleLiteralAttribute){
        out.print("DOUBLE_LITERAL ");
        out.print(":");
        out.print(doubleLiteralAttribute.getName());
        out.print(" ");
    }

   public static String booleanLiteralAttributeToString(BooleanLiteralAttribute booleanLiteralAttribute){
        StringWriter writer=new StringWriter();
        Lang4jRenderer renderer=new Lang4jRenderer(writer);
        renderer.renderBooleanLiteralAttribute(booleanLiteralAttribute);
        return writer.getBuffer().toString();
    }
    public void renderBooleanLiteralAttribute(BooleanLiteralAttribute booleanLiteralAttribute){
        out.print("BOOLEAN_LITERAL ");
        out.print(":");
        out.print(booleanLiteralAttribute.getName());
        out.print(" ");
    }

   public static String referenceAttributeToString(ReferenceAttribute referenceAttribute){
        StringWriter writer=new StringWriter();
        Lang4jRenderer renderer=new Lang4jRenderer(writer);
        renderer.renderReferenceAttribute(referenceAttribute);
        return writer.getBuffer().toString();
    }
    public void renderReferenceAttribute(ReferenceAttribute referenceAttribute){
        out.print("REFERENCE ");
        out.print(":");
        out.print(referenceAttribute.getName());
        out.print(" ");
        out.print(":");
        out.print(referenceAttribute.getProduction().getName());
        out.print(" ");
    }

   public static String attributeToString(Attribute attribute){
        StringWriter writer=new StringWriter();
        Lang4jRenderer renderer=new Lang4jRenderer(writer);
        renderer.renderAttribute(attribute);
        return writer.getBuffer().toString();
    }
    public void renderAttribute(Attribute attribute){
    attribute.accept(new AttributeVisitor(){
        public void visitDeepAttribute(DeepAttribute deepAttribute){
            renderDeepAttribute(deepAttribute);
        }
        public void visitFlatAttribute(FlatAttribute flatAttribute){
            renderFlatAttribute(flatAttribute);
        }
    });
    }

   public static String charTokenToString(CharToken charToken){
        StringWriter writer=new StringWriter();
        Lang4jRenderer renderer=new Lang4jRenderer(writer);
        renderer.renderCharToken(charToken);
        return writer.getBuffer().toString();
    }
    public void renderCharToken(CharToken charToken){
        out.print("'"+StringEscapeUtils.escapeJava(Character.toString(charToken.getText()))+"'");
        out.print(" ");
    }

   public static String keywordToString(Keyword keyword){
        StringWriter writer=new StringWriter();
        Lang4jRenderer renderer=new Lang4jRenderer(writer);
        renderer.renderKeyword(keyword);
        return writer.getBuffer().toString();
    }
    public void renderKeyword(Keyword keyword){
        out.print("\""+StringEscapeUtils.escapeJava(keyword.getText())+"\"");
        out.print(" ");
    }

   public static String terminalToString(Terminal terminal){
        StringWriter writer=new StringWriter();
        Lang4jRenderer renderer=new Lang4jRenderer(writer);
        renderer.renderTerminal(terminal);
        return writer.getBuffer().toString();
    }
    public void renderTerminal(Terminal terminal){
    terminal.accept(new TerminalVisitor(){
        public void visitCharToken(CharToken charToken){
            renderCharToken(charToken);
        }
        public void visitKeyword(Keyword keyword){
            renderKeyword(keyword);
        }
    });
    }




}
